package com.tyj.tuyijieapp.config.security;

import com.tyj.tuyijieapp.config.security.captcha.CaptchaProviderToken;
import com.tyj.tuyijiecommon.exception.ExpirationException;
import com.tyj.tuyijiecommon.util.JwtUtil;
import com.tyj.tuyijiesystem.model.juser.service.auth.AuthServiceImpl;
import lombok.SneakyThrows;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * <p></p>
 *
 * @author lhf
 * @since 2020/6/7
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {


    @Resource
    private AuthServiceImpl authService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;


    @SneakyThrows
    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        String token = request.getHeader("Authorization");

//        如果没有token直接放行
        if (token == null || token.isEmpty()) {
            filterChain.doFilter(request, response);
            return;
        }
//        走过滤器
        String phone = null;
        try {
            phone = JwtUtil.getUsernameFromToken(token);
            JwtUtil.isExpiration(token);

//            刷新token
            String newToken = JwtUtil.refreshToken(token);
            redisTemplate.opsForValue().set("login:user:" + phone, newToken,30, TimeUnit.MINUTES);
//            添加到响应头中
            response.addHeader("Authorization", newToken);
        } catch (Exception e) {
            throw new ExpirationException("登录超时");
        }
        //判断用户不为空，且SecurityContextHolder授权信息还是空的

        if (phone != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            //通过用户信息得到UserDetails
            UserDetails userDetails = authService.loadUserByUsername(phone);
            if (!JwtUtil.validateToken(token, userDetails)) {
                return;
            }
            CaptchaProviderToken authentication = new CaptchaProviderToken(userDetails, userDetails.getPassword());
            //设置用户已认证，否者他会一直走认证，还不会通过，因为这里没有验证码
            authentication.setAuthenticated(true);
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request, response);
    }

}
